package com.cloudservice.ccs.exception;

import com.cloudservice.ccs.model.ApiResult;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.multipart.MaxUploadSizeExceededException;

@RestControllerAdvice
public class GlobalExceptionHandler {

    private final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    /**
     * 处理 BaseException（以及其子类）并返回对应的错误响应
     */
    @ExceptionHandler(BaseException.class)
    public ApiResult handleBaseException(BaseException e) {
        logException(e);
        return new ApiResult(e.getError(), e.getMessage());
    }

    /**
     * 处理认证、鉴权相关异常并返回对应的错误响应
     */
    @ExceptionHandler(AuthenticationException.class)
    public ApiResult handleAuthenticationException(AuthenticationException e) {
        logException(e);
        if (e instanceof UnknownAccountException) {
            return ApiResult.failureWithData("未知用户");
        } else if (e instanceof IncorrectCredentialsException) {
            return ApiResult.failureWithData("用户名或密码错误");
        } else {
            return ApiResult.failureWithData("未知认证错误：" + e.getClass().getName() + ": " + e.getMessage());
        }
    }

    @ExceptionHandler(MaxUploadSizeExceededException.class)
    public ApiResult handleMaxUploadSizeExceededException(MaxUploadSizeExceededException e) {
        logException(e);
        return new ApiResult("文件上传失败", "上传文件大小超出限制");
    }

    @ExceptionHandler(Exception.class)
    public ApiResult handleException(Exception e) {
        logException(e);
        return ApiResult.failureWithData("未知错误：" + e.getClass().getName() + ": " + e.getMessage());
    }

    private void logException(Exception e) {
        if (logger.isDebugEnabled()) {
            logger.debug(e.getClass().getName() + ": " + e.getMessage());
            e.printStackTrace();
        }
    }
}
